package com.sky.service.impl;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.sky.constant.MessageConstant;
import com.sky.dto.SetmealDTO;
import com.sky.dto.SetmealPageQueryDTO;
import com.sky.entity.Category;
import com.sky.entity.Dish;
import com.sky.entity.Setmeal;
import com.sky.entity.SetmealDish;
import com.sky.exception.SetmealEnableFailedException;
import com.sky.mapper.CategoryMapper;
import com.sky.mapper.DishMapper;
import com.sky.mapper.SetmealDishMapper;
import com.sky.mapper.SetmealMapper;
import com.sky.result.PageResult;
import com.sky.service.SetmealService;
import com.sky.vo.DishItemVO;
import com.sky.vo.SetmealVO;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class SetmealServiceImpl implements SetmealService {

    @Autowired
    private SetmealMapper setmealMapper;

    @Autowired
    private SetmealDishMapper setmealDishMapper;

    @Autowired
    private DishMapper dishMapper;

    @Autowired
    private CategoryMapper categoryMapper;

    @Transactional
    @Override
    public void save(SetmealDTO dto) {
//        多表修改，开启事务
//        套餐名字已存在抛异常
        Setmeal setmeal = setmealMapper.getByName(dto.getName());
        if(null != setmeal)
            throw new RuntimeException("套餐名已存在...");
        setmeal = new Setmeal();
        BeanUtils.copyProperties(dto, setmeal);
//        套餐id主键返回
//        含有自动填充字段
        setmealMapper.save(setmeal);
//        添加套餐和菜品的关系      setmeal_dish
        for (SetmealDish setmealDish : dto.getSetmealDishes()) {
            //获取主键返回
            setmealDish.setSetmealId(setmeal.getId());
            setmealDishMapper.save(setmealDish);
        }

        clearRedis(dto.getCategoryId());
    }

    @Override
    public PageResult page(SetmealPageQueryDTO dto) {
        PageHelper.startPage(dto.getPage(), dto.getPageSize());
//        按修改时间排序
//        套餐名称模糊查询
//        状态
//        分类
//        查询套餐基本表就可以     setmeal
        Page<Setmeal> page = setmealMapper.page(dto);
        List<SetmealVO> vos = page.getResult().stream().map(setmeal -> {
            SetmealVO vo = new SetmealVO();
            //分类名称查询
            BeanUtils.copyProperties(setmeal, vo);
            Category category = categoryMapper.get(setmeal.getCategoryId());
            vo.setCategoryName(category.getName());
            return vo;
        }).collect(Collectors.toList());
        return PageResult.builder()
                .total(page.getTotal())
                .records(vos).build();
    }

    @Transactional
    @Override
    public void dels(String[] split) {
        // 多表，多条数据修改，开启事务
        Arrays.stream(split).forEach(s -> {
            long id = Long.parseLong(s);
            // 启售套餐不能删除
            Setmeal setmeal = setmealMapper.getById(id);
            if(1 == setmeal.getStatus())
                throw new SetmealEnableFailedException(MessageConstant.SETMEAL_ON_SALE);
            // 基础信息删除了， 套餐和菜品关系表也要删除
            setmealMapper.delById(id);
            setmealDishMapper.delBySetmealId(id);

            // 清理redis缓存
            clearRedis(setmeal.getCategoryId());
        });
    }

    @Override
    public SetmealVO info(long parseLong) {
        Setmeal setmeal = setmealMapper.getById(parseLong);
        SetmealVO vo = new SetmealVO();
        BeanUtils.copyProperties(setmeal, vo);
        //查询套餐和菜品关系信息
        vo.setSetmealDishes(setmealDishMapper.getBySetmealId(parseLong));
        return vo;
    }

    @Transactional
    @Override
    public void update(SetmealDTO dto) {
//        需要修改的套餐名已存在抛异常
        Setmeal setmeal = setmealMapper.getByName(dto.getName());
        if(null != setmeal && setmeal.getId() != dto.getId())
            throw new RuntimeException("套餐名已存在...");
        if (null == setmeal)
            setmeal = new Setmeal();
        BeanUtils.copyProperties(dto, setmeal);
        setmealMapper.updateById(setmeal);
//        套餐和菜品关系先删后添加
//        添加的套餐和菜品关系无论如何都设置一下套餐id
        setmealDishMapper.delBySetmealId(setmeal.getId());
        for (SetmealDish setmealDish : dto.getSetmealDishes()) {
            setmealDish.setSetmealId(setmeal.getId());
            setmealDishMapper.save(setmealDish);
        }

        // 清理redis缓存
        clearRedis(setmeal.getCategoryId());
    }

    @Override
    public void status(Long parseLong, Integer parseInt) {
        Setmeal setmeal = setmealMapper.getById(parseLong);
//        菜品禁售，套餐不能启售
        if(1==parseInt){
            List<SetmealDish> setmealDishList = setmealDishMapper.getBySetmealId(parseLong);
            setmealDishList.forEach(setmealDish -> {
                Dish dish = dishMapper.getById(setmealDish.getDishId());
                if(0 == dish.getStatus())
                    throw new RuntimeException(MessageConstant.SETMEAL_ENABLE_FAILED);
            });
        }
        setmealMapper.updateById(Setmeal.builder().status(parseInt).id(parseLong).build());

        // 清理redis缓存
        clearRedis(setmeal.getCategoryId());
    }

    /**
     * 条件查询
     * @param setmeal
     * @return
     */
    public List<Setmeal> list(Setmeal setmeal) {
        List<Setmeal> list = setmealMapper.list(setmeal);
        return list;
    }

    /**
     * 根据id查询菜品选项
     * @param id
     * @return
     */
    public List<DishItemVO> getDishItemById(Long id) {
        return setmealMapper.getDishItemBySetmealId(id);
    }

    @CacheEvict(value = "setmeal_list_category_id", key = "#categoryId")
    public void clearRedis(Long categoryId){}
}
